'use strict';
// Copyright 2014 Blueant Inc. All Rights Reserved.

/**
 * @fileoverview 登陆服务器
 * @author sundbcn@gmail.com (sun debing)
 */

var _ = require('lodash');
var moment = require('moment');
var pomelo = require('pomelo');
var async = require('async');
var Code = require('../../../consts/code');
var PlayerManager = require('../../../libs/playerManager');
var roleModel = require('../../../models/roleModel');
var activityModel = require('../../../models/activityModel');
var userModel = require('../../../models/userModel');
var serverStatusModel = require('../../../models/serverStatusModel.js');
var channelUtil = require('../../../util/channelUtil');
var battleService = require('../../../services/battleService');
var roleService = require('../../../services/roleService.js');
var skillService = require('../../../services/skillService.js');
var onlineUserCountService = require('../../../services/onlineUserCountService.js');
var analyze = require('../../../libs/analyze');
var dataApi = require('../../../libs/dataApi');
var fightPowerService = require('../../../services/fightPowerService');
var activityService = require('../../../services/activityService');
var arenaService = require('../../../services/arenaService');
var actType = require('../../../consts/activityType.js');
var unionGroupModel = require('../../../models/unionGroupModel.js');
var buildType = require('../../../consts/buildType.js');
var rewardService = require('../../../services/rewardService.js');
var offlineConf = require('../../../config/offlineConf.js');
var taskSynchronizationService = require('../../../services/taskSynchronizationService.js');
var unionHelpModel = require('../../../models/unionHelpModel.js');
var haveHelpModel = require('../../../models/haveHelpModel.js');
var unionGroupMgr = require('../../../mgr/unionGroupMgr.js');
var haveHelpMgr = require('../../../mgr/haveHelpMgr.js');
var moduleType = require('../../../consts/moduleType.js');
var operationType = require('../../../consts/operationType');

module.exports = function (app) {
    return new Handler(app);
};

var Handler = function (app) {
    this.app = app;
    this.globalChannelService = app.get('globalChannelService');
};

var _showLog = function (msg) {
    // console.log(msg);
};

/**
 * 新用户登陆
 */
Handler.prototype.entry = function (msg, session, next) {
    _showLog('--- connector.entryRolehandler.entry() -----------');
    var self = this;
    var auth_uid = session.get('auth_uid');
    var job_type = msg.job_type;

    if (!job_type) {
        return next(null, {
            code: Code.PARAM_ERROR
        });
    }

    if (!auth_uid) {
        return next(null, {
            code: Code.ENTRY_AUTH_UID_NOT_FOUND
        });
    }
    var union_group_model = null;
    var role_id;
    var player_manager;
    var battle_record;
    var sessionService;
    var union_id = 0;
    var channel_id;
    var create_time;
    var last_login_day = 0;
    var only_id_list = [];
    var help_list = [];
    var have_info = [];
    var union_help_msg = {};
    var role_model;
    async.waterfall(
        [
            function (cb) {
                serverStatusModel.isGameLocked(cb);
            },
            function (game_locked, cb) {
                console.log('------ game_locked:', game_locked);
                if (game_locked) {
                    // 服务器已锁定(停服维护)
                    return next(null, {
                        code: Code.ENTRY_SERVER_LOCKED
                    });
                }

                arenaService.createNpc(cb);
            },
            function (cb) {
                _showLog('--- getByJob() -----------');
                roleModel.getByJob(auth_uid, job_type, cb);
            },
            function (model, cb) {
                if (!model) {
                    return next(null, {
                        code: Code.ENTRY_CAN_NOT_PASS
                    });
                }
                role_id = model.getRoleId();
                union_id = model.union_id;
                create_time = model.create_time;
                session.set('union_id', union_id);

                sessionService = pomelo.app.get('sessionService');
                var old_session = sessionService.getByUid(role_id);
                if (!old_session) {
                    return cb();
                }
                if (old_session[0].id !== session.id) {
                    sessionService.kickBySessionId(old_session[0].id, 'kick_old_session', cb);
                    return;
                }
                cb();
            },
            function (cb) {
                session.bind(role_id, cb);
            },
            function (cb) {
                session.on('closed', onUserLeave.bind(self, self.app));
                session.pushAll(cb);
            },
            function (cb) {
                channel_id = session.get('channel_id');
                onlineUserCountService.addOnlineUser(channel_id, cb);
            },
            function (cb) {
                _showLog('--- getAllModel() -----------');
                player_manager = new PlayerManager(role_id);
                player_manager.getAllModel(cb);
            },
            function (cb) {
                _showLog('--- _migrate_skill() -----------');
                skillService.migrateSkill(player_manager);
                _migrateSoldierTalent(player_manager);

                _showLog('--- refreshData() -----------');
                player_manager.refreshData(cb);
            },
            function (cb) {
                _showLog('--- task----tackle -----------');
                taskSynchronizationService.synchronization(player_manager, cb);
            },
            function (cb) {
                _showLog('--- addToGlobalChannel() -----------');
                self.globalChannelService.add(channelUtil.getGlobalChannelName(), role_id, self.app.get('serverId'), cb);
            },
            function (cb) {

                if (!!union_id) {
                    _showLog('--- addToUnionChannel() union_id -*******-----------');
                    self.globalChannelService.add(union_id, role_id, self.app.get('serverId'), cb);
                } else {
                    cb();
                }
            },
            function (cb) {
                var activity_model = player_manager.activity;
                role_model = player_manager.role;
                var build_model = player_manager.build;
                var leave_time = role_model.last_logout_time;
                var leave_now_time = moment();
                var diff_day = leave_now_time.diff(leave_time, 'days');
                if (diff_day >= 3) {
                    var nexus_lv = build_model.getBuildByType(buildType.NEXUS);
                    var reward_all = offlineConf.getConf(nexus_lv.lv, diff_day);
                    var reward_list = reward_all.reward_list;
                    last_login_day = reward_all.day;

                    // 发放奖励
                    for (var i = 0; i < reward_all.day_ratio; i++) {
                        rewardService.addRewardListToRole(player_manager, reward_list, moduleType.MDL_ENTRYROLE, operationType.OPR_LEAVE_REWARD);
                    }
                }

                // 计算累计登陆天数
                if (moment(role_model.getLastLoginTime()) < moment().startOf('day')) {
                    activity_model.addContinuouslyLoginDays();
                }

                if (role_model.hero_power === 0) {
                    fightPowerService.initFightPower(player_manager);
                }
                cb();
            },
            function (cb) {
                _showLog('--- roleModel.login() -----------');
                roleModel.login(role_id, cb);
            },
            function (cb) {
                _showLog('--- getRecordList() -----------');
                battleService.getRecordList(role_id, cb);
            },
            function (record, cb) {
                battle_record = record;
                userModel.getByUid(auth_uid, cb);
            },
            function (user_model, cb) {
                if (user_model.isForbid()) {
                    return next(null, {
                        code: Code.ENTRY_HAVE_FORBID
                    });
                }
                _showLog('--- setLastLoginJobType() -----------');
                user_model.setLastLoginJobType(job_type);
                user_model.save(function (err) {
                    cb();
                });
            },
            function (cb) {
                _showLog('--- before get haveHelp -----------');
                haveHelpModel.findUnionHelpList(role_id, function (err, have_list_all) {
                    have_info = have_list_all;
                    cb();
                });
            },
            function (cb) {
                if (!!union_id) {

                    unionGroupModel.getById(union_id, function (err, union_model) {
                        _showLog('--- back from get union info -----------');
                        if (!!err) {
                            console.error('err------------union mgr not ', err);
                        }
                        union_group_model = union_model;

                        // 如果有联盟同步联盟名到角色schema中
                        if (!role_model.union_name) {
                            role_model.union_name = union_group_model.name;
                        }
                        if (!role_model.union_flag) {
                            role_model.union_flag = union_group_model.union_flag;
                        }
                        cb();
                    });
                } else {
                    _showLog('--- not join union -----------');
                    cb();
                }
            },
            function (cb) {
                if (!!union_id) {
                    unionHelpModel.findUnionHelpList(union_id, function (err, help_list1) {
                        help_list = help_list1;
                        cb();
                    });
                } else {
                    cb();
                }
            },

            function (cb) {
                if (!!union_id) {
                    union_help_msg = {
                        is_modify: 4,
                        help_list: help_list
                    };
                    cb();
                } else {
                    cb();
                }
            }
        ],
        function (err) {
            _showLog('--- before exit entryRoleHandler -----------');
            if (!!err) {
                console.error(err);
                return next(null, {
                    code: Code.FAIL
                });
            }
            _analyzeLogin(role_id, channel_id, create_time);
            player_manager.save();
            player_manager.push();
            if (!!union_group_model) {
                _showLog('------------- push union info ------');
                union_group_model.pushModifyToRole(role_id);

                haveHelpMgr.sendHaveHelpChanged(
                    role_id, {
                        have_list: have_info,
                        is_modify: 1
                    },
                    function (err, fails) {
                        if (err) {
                            console.error('send unionGroup message error: %j, fail ids: %j', err, fails);
                            return;
                        }
                        _showLog('-----push have_info end --------------');
                        //cb();
                    }
                );
                unionGroupMgr.sendUnionHelpChangedOnly(
                    role_id,
                    union_help_msg,
                    function (err, fails) {
                        if (err) {
                            console.error('send unionGroup message error: %j, fail ids: %j', err, fails);
                            return;
                        }
                        _showLog('-----push union_help_msg end --------------');
                        //cb();
                    }
                );
            }
            activityService.push(role_id, actType.ALL, player_manager);
            _showLog('--- end of entryRoleHandler -----------');
            return next(null, {
                code: Code.OK,
                result: {
                    player: {
                        build: player_manager.build.toJSON(),
                        guide: player_manager.guide.toJSON()
                    },
                    current_time: moment().unix(),
                    battle_record: battle_record,
                    last_login_day: last_login_day
                }
            });
        }
    );
};

var onUserLeave = function (app, session) {
    if (!session || !session.uid) {
        return;
    }

    roleModel.logout(session.uid, function (err) {
        if (err) {
            console.error('role %s logout failed, error %j: ', session.uid, err);
        }
    });

    this.globalChannelService.leave(channelUtil.getGlobalChannelName(), session.uid, app.get('serverId'), function (err) {
        if (err) {
            console.error('role %s leave failed, error %j: ', session.uid, err);
        }
    });

    var union_id_leave = session.get('union_id');
    this.globalChannelService.leave(union_id_leave, session.uid, app.get('serverId'), function (err) {
        if (err) {
            console.error('role %s leave failed, error %j , union_id: ', session.union_id, err);
        }
    });

    var channel_id = session.get('channel_id');
    roleModel.getByRoleId(session.uid, function (err, role_model) {
        if (!!role_model) {
            var last_login_time = moment(role_model.getLastLoginTime()).unix();
            var now_time = moment().unix();
            role_model.last_logout_time = now_time;
            var diff = Math.ceil((now_time - last_login_time) / 60);
            _analyzeOnlineTime(session.uid, channel_id, diff);
        }

        onlineUserCountService.subOnlineUser(channel_id);
    });
};

/**
 * 统计登录
 * @param  {[type]} role_id [description]
 * @return {[type]}         [description]
 */
var _analyzeLogin = function (role_id, channel_id, create_time) {
    analyze.recordLogin(role_id, channel_id, create_time);
};

/**
 * 统计在线时间
 * @param  {[type]} role_id [description]
 * @return {[type]}         [description]
 */
var _analyzeOnlineTime = function (role_id, channel_id, time) {
    analyze.recordOnlineTime(role_id, channel_id, time);
};

/**
 * 统计在线时间
 * @param  {[type]} role_id [description]
 * @return {[type]}         [description]
 */
var _migrateSoldierTalent = function (player_manager) {
    var soldier_model = player_manager.soldier;

    _.forEach(soldier_model.soldier_list, function (soldier_item) {
        if (soldier_item.talent.length === 0) {
            soldier_item.initTalent();
        }
    });
};
